<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8"/>
        <title>bind、call、apply和new</title>
    </head>
    <body>
            bind、call、apply和new
    </body>
    <script>
        // bind
        Function.prototype.myBind = function() {
            const o = [].shift.call(arguments)
            const others = [...arguments]
            const _this = this
            return function() {
                _this.apply(o, [].concat.apply(others, [...arguments]))
            }
        }
        const bindObj = {name: 'bind'}
        function bindFn () {
            console.log('bindFn', this)
            console.log('bindArguments', [...arguments])
        }
        bindFn.myBind(bindObj, 1, 2, 3)(4)
        // call
        Function.prototype.myCall = function(context) {
            context = context ? context : window;
            context.fn = this
            context.fn(...[...arguments].slice(1))
            delete context.fn
        }
        const callObj = { name: 'call' }
        function callFn(a, b, c) {
            console.log('callFn', this)
            console.log('callArguments', arguments)
            console.log('callParams', a, b, c)
        }
        callFn.myCall(callObj, 1, 2, 3)
        // apply
        Function.prototype.myApply= function(context) {
            context = context ? context : window;
            context.fn = this
            context.fn([...arguments][1])
            delete context.fn 
        }
        const applyObj = { name: 'apply' }
        function applyFn(param) {
            console.log('applyFn', this)
            console.log('applyArguments', arguments)
            console.log('applyParams', param)
        }
        applyFn.myApply(applyObj, [1, 2, 3])
        // new
        function copyNew() {
            const f = [].shift.call(arguments)
            const obj = {}
            f.apply(obj, arguments)
            obj.__proto__ = f.prototype
            return obj
        }

        function colorsFn(color) {
            this.color = color
        }

        colorsFn.prototype.opacity = 1
        colorsFn.prototype.say = function() {}

        const copynewObj = copyNew(colorsFn, 'red')

        console.log('color', copynewObj.color)
        console.log('opacity', copynewObj.opacity)
        console.log('copynewObj', copynewObj)
    </script>
</html>